/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package DAO;

import DAO.exceptions.IllegalOrphanException;
import DAO.exceptions.NonexistentEntityException;
import DAO.exceptions.PreexistingEntityException;
import DAO.exceptions.RollbackFailureException;
import java.io.Serializable;
import javax.persistence.Query;
import javax.persistence.EntityNotFoundException;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import Entidad.Proyecto;
import Entidad.Actividad;
import Entidad.Flujo;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.transaction.UserTransaction;

/**
 *
 * @author David
 */
public class FlujoDAO implements Serializable, DAOinterface{

    public void create(Flujo flujo, EntityManager em)  {
        if (flujo.getActividadCollection() == null) {
            flujo.setActividadCollection(new ArrayList<Actividad>());
        }
            Proyecto idproyecto = flujo.getIdproyecto();
            if (idproyecto != null) {
                idproyecto = em.getReference(idproyecto.getClass(), idproyecto.getIdproyecto());
                flujo.setIdproyecto(idproyecto);
            }
            Collection<Actividad> attachedActividadCollection = new ArrayList<Actividad>();
            for (Actividad actividadCollectionActividadToAttach : flujo.getActividadCollection()) {
                actividadCollectionActividadToAttach = em.getReference(actividadCollectionActividadToAttach.getClass(), actividadCollectionActividadToAttach.getIdactividad());
                attachedActividadCollection.add(actividadCollectionActividadToAttach);
            }
            flujo.setActividadCollection(attachedActividadCollection);
            em.persist(flujo);
            if (idproyecto != null) {
                idproyecto.getFlujoCollection().add(flujo);
                idproyecto = em.merge(idproyecto);
            }
            for (Actividad actividadCollectionActividad : flujo.getActividadCollection()) {
                Flujo oldIdflujoOfActividadCollectionActividad = actividadCollectionActividad.getIdflujo();
                actividadCollectionActividad.setIdflujo(flujo);
                actividadCollectionActividad = em.merge(actividadCollectionActividad);
                if (oldIdflujoOfActividadCollectionActividad != null) {
                    oldIdflujoOfActividadCollectionActividad.getActividadCollection().remove(actividadCollectionActividad);
                    oldIdflujoOfActividadCollectionActividad = em.merge(oldIdflujoOfActividadCollectionActividad);
                }
            }
            
    }

    public void edit(Flujo flujo, EntityManager em) throws IllegalOrphanException, NonexistentEntityException, RollbackFailureException, Exception {
        try {
            Flujo persistentFlujo = em.find(Flujo.class, flujo.getIdflujos());
            Proyecto idproyectoOld = persistentFlujo.getIdproyecto();
            Proyecto idproyectoNew = flujo.getIdproyecto();
            Collection<Actividad> actividadCollectionOld = persistentFlujo.getActividadCollection();
            Collection<Actividad> actividadCollectionNew = flujo.getActividadCollection();
            List<String> illegalOrphanMessages = null;
            for (Actividad actividadCollectionOldActividad : actividadCollectionOld) {
                if (!actividadCollectionNew.contains(actividadCollectionOldActividad)) {
                    if (illegalOrphanMessages == null) {
                        illegalOrphanMessages = new ArrayList<String>();
                    }
                    illegalOrphanMessages.add("You must retain Actividad " + actividadCollectionOldActividad + " since its idflujo field is not nullable.");
                }
            }
            if (illegalOrphanMessages != null) {
                throw new IllegalOrphanException(illegalOrphanMessages);
            }
            if (idproyectoNew != null) {
                idproyectoNew = em.getReference(idproyectoNew.getClass(), idproyectoNew.getIdproyecto());
                flujo.setIdproyecto(idproyectoNew);
            }
            Collection<Actividad> attachedActividadCollectionNew = new ArrayList<Actividad>();
            for (Actividad actividadCollectionNewActividadToAttach : actividadCollectionNew) {
                actividadCollectionNewActividadToAttach = em.getReference(actividadCollectionNewActividadToAttach.getClass(), actividadCollectionNewActividadToAttach.getIdactividad());
                attachedActividadCollectionNew.add(actividadCollectionNewActividadToAttach);
            }
            actividadCollectionNew = attachedActividadCollectionNew;
            flujo.setActividadCollection(actividadCollectionNew);
            flujo = em.merge(flujo);
            if (idproyectoOld != null && !idproyectoOld.equals(idproyectoNew)) {
                idproyectoOld.getFlujoCollection().remove(flujo);
                idproyectoOld = em.merge(idproyectoOld);
            }
            if (idproyectoNew != null && !idproyectoNew.equals(idproyectoOld)) {
                idproyectoNew.getFlujoCollection().add(flujo);
                idproyectoNew = em.merge(idproyectoNew);
            }
            for (Actividad actividadCollectionNewActividad : actividadCollectionNew) {
                if (!actividadCollectionOld.contains(actividadCollectionNewActividad)) {
                    Flujo oldIdflujoOfActividadCollectionNewActividad = actividadCollectionNewActividad.getIdflujo();
                    actividadCollectionNewActividad.setIdflujo(flujo);
                    actividadCollectionNewActividad = em.merge(actividadCollectionNewActividad);
                    if (oldIdflujoOfActividadCollectionNewActividad != null && !oldIdflujoOfActividadCollectionNewActividad.equals(flujo)) {
                        oldIdflujoOfActividadCollectionNewActividad.getActividadCollection().remove(actividadCollectionNewActividad);
                        oldIdflujoOfActividadCollectionNewActividad = em.merge(oldIdflujoOfActividadCollectionNewActividad);
                    }
                }
            }
        } catch (Exception ex) {
            String msg = ex.getLocalizedMessage();
            if (msg == null || msg.length() == 0) {
                Integer id = flujo.getIdflujos();
                if (findFlujo(id, em) == null) {
                    throw new NonexistentEntityException("The flujo with id " + id + " no longer exists.");
                }
            }
            throw ex;
        }
    }

    public void destroy(Integer id, EntityManager em) throws IllegalOrphanException, NonexistentEntityException, RollbackFailureException, Exception {
            Flujo flujo;
            try {
                flujo = em.getReference(Flujo.class, id);
                flujo.getIdflujos();
            } catch (EntityNotFoundException enfe) {
                throw new NonexistentEntityException("The flujo with id " + id + " no longer exists.", enfe);
            }
            List<String> illegalOrphanMessages = null;
            Collection<Actividad> actividadCollectionOrphanCheck = flujo.getActividadCollection();
            for (Actividad actividadCollectionOrphanCheckActividad : actividadCollectionOrphanCheck) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("This Flujo (" + flujo + ") cannot be destroyed since the Actividad " + actividadCollectionOrphanCheckActividad + " in its actividadCollection field has a non-nullable idflujo field.");
            }
            if (illegalOrphanMessages != null) {
                throw new IllegalOrphanException(illegalOrphanMessages);
            }
            Proyecto idproyecto = flujo.getIdproyecto();
            if (idproyecto != null) {
                idproyecto.getFlujoCollection().remove(flujo);
                idproyecto = em.merge(idproyecto);
            }
            em.remove(flujo);
    }

    public List<Flujo> findFlujoEntities(EntityManager em) {
        return findFlujoEntities(true, -1, -1, em);
    }

    public List<Flujo> findFlujoEntities(int maxResults, int firstResult, EntityManager em) {
        return findFlujoEntities(false, maxResults, firstResult, em);
    }

    private List<Flujo> findFlujoEntities(boolean all, int maxResults, int firstResult, EntityManager em) {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            cq.select(cq.from(Flujo.class));
            Query q = em.createQuery(cq);
            if (!all) {
                q.setMaxResults(maxResults);
                q.setFirstResult(firstResult);
            }
            return q.getResultList();
    }

    public Flujo findFlujo(Integer id, EntityManager em) {
        return em.find(Flujo.class, id);
    }

    public int getFlujoCount(EntityManager em) {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            Root<Flujo> rt = cq.from(Flujo.class);
            cq.select(em.getCriteriaBuilder().count(rt));
            Query q = em.createQuery(cq);
            return ((Long) q.getSingleResult()).intValue();
    }
    
}
